/*
* Copyright (c) 2007 by Kirill Kolodyazhniy.
* See the file "license.terms" for information on usage and redistribution.
*/

#include "octreenode.h"

#ifdef _DEBUG
#ifdef _MSC_VER
   #define new new( _CLIENT_BLOCK, __FILE__, __LINE__)
#endif
#endif // _DEBUG

namespace Engine
{
	/**********************************************************************************************************/
	OctreeNode::OctreeNode(OctreeSceneManager* creator,const std::string& name )
		:SceneNode(name)
		,m_octant(0)
		,m_creator(creator)
	{
	}
	/**********************************************************************************************************/
	OctreeNode::~OctreeNode()
	{
		m_creator->RemoveOctreeNode(this);
	}
	/**********************************************************************************************************/
	bool OctreeNode::IsIn( const AABB& box )
	{
		if(box.IsNull())
			return false;

		AABB worldAABB = GetBoundingBox();

		Vector3<REAL> center = (worldAABB.GetMaximum()+ worldAABB.GetMinimum() )* 0.5;

		Vector3<REAL> bmin = box.GetMinimum();
		Vector3<REAL> bmax = box.GetMaximum();

		//bool centre = ( bmax > center && bmin < center );
		bool centre = ( bmax.x >= center.x && bmax.y >= center.y && bmax.z >= center.z && bmin.x < center.x && bmin.y < center.y && bmin.z < center.z);
		if (!centre)
			return false;

		Vector3<REAL> octreeSize = bmax - bmin;
		Vector3<REAL> nodeSize = worldAABB.GetMaximum() - worldAABB.GetMinimum();
		return nodeSize < octreeSize;
	}
	/**********************************************************************************************************/
	void OctreeNode::UpdateBounds( void )
	{
		SceneNode::UpdateBounds();

		m_creator->UpdateOctreeNode( this );
	}
	/**********************************************************************************************************/
	SceneNodePtr OctreeNode::CreateChild(const std::string& name)
	{
		if(!CheckChildName(name))
			throw std::invalid_argument("SceneNode with same name already exists " + name);

		OctreeNode* node =  new OctreeNode(m_creator,name);
		return AddChildNode(node);
	}
	/**********************************************************************************************************/
	void OctreeNode::AddToRenderQueue(const Camera* camera, RenderQueue* renderqueue, RenderQueue* shadowsQueue, const std::vector<LightPtr>& lightList,Visibility vis)
	{
		FindVisibleMovableObjects(camera,renderqueue,shadowsQueue,lightList,vis);
	}
	/**********************************************************************************************************/
}

